#!/usr/bin/env python 
# -*- coding: utf-8 -*-
# @Time    : 2023/3/4 17:05
# @Author  : WJQ
# @Site    : 
# @File    : click_handler.py.py
# @Software: PyCharm
import time
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.common.touch_action import TouchAction
from appium.webdriver.webelement import WebElement
import conf

from models.Graph import Component
from utils.common import CrawlerLogger
from browser.page import PageHandler

class ClickHandler:
    def __init__(self, driver_handler):
        self.driver_handler = driver_handler

    def safe_click ( self, element: WebElement, state: str ) :
        '''
        safe 点击元素
        '''
        try :
            element.click()
            time.sleep(2)
            CrawlerLogger.info(f"[+] Click {element.text} at {state}")
            return True
        except Exception as e :
            CrawlerLogger.debug(f"[-] Click error at {state}: {e}")
            return False

    def safe_click_by_location_or_scroll ( self, element: Component, state: str, timeout=2 ) :
        '''
        safe 点击元素
        :param element:
        :return:
        '''
        element.visited = True
        try:
            self.driver_handler.driver.implicitly_wait(timeout)
            if (element.x + element.width // 2) > conf.CLIENT_SIDE_CONF.PHONE_WIDTH or \
                    (element.y + element.height // 2) > conf.CLIENT_SIDE_CONF.PHONE_HEIGHT:
                CrawlerLogger.debug(f"[-] click element out of screen")
                return False
            if element.method == 'click' :
                x_position = element.x + element.width // 2
                y_position = element.y + element.height // 2
                
                try:
                    # 方法1: 使用clickGesture JavaScript命令
                    self.driver_handler.driver.execute_script(
                        'mobile: clickGesture', 
                        {'x': x_position, 'y': y_position}
                    )
                except Exception as e1:
                    CrawlerLogger.debug(f"[-] clickGesture method failed: {e1}")
                    try:
                        # 方法2: 使用直接的tap方法
                        self.driver_handler.driver.tap([(x_position, y_position)])
                    except Exception as e2:
                        CrawlerLogger.debug(f"[-] Tap method failed: {e2}")
                        # 所有方法都失败，抛出异常
                        raise Exception("All click methods failed")
                
                CrawlerLogger.info(f"[+] Click {element.label} in {state}")
                time.sleep(timeout)
                return True
            elif element.method == 'scroll' :
                CrawlerLogger.info(f"[+] scroll the phone")
                start_x = 720
                start_y = int(conf.CLIENT_SIDE_CONF.PHONE_HEIGHT * 0.9)
                end_x = 720
                end_y = int(conf.CLIENT_SIDE_CONF.PHONE_HEIGHT * 0.1)
                
                try:
                    # 方法1: 使用swipeGesture JavaScript命令
                    self.driver_handler.driver.execute_script(
                        'mobile: swipeGesture', 
                        {
                            'left': start_x, 
                            'top': start_y, 
                            'width': 10, 
                            'height': start_y - end_y,
                            'direction': 'up',
                            'percent': 1.0
                        }
                    )
                except Exception as e1:
                    CrawlerLogger.debug(f"[-] swipeGesture method failed: {e1}")
                    try:
                        # 方法2: 使用直接的swipe方法
                        self.driver_handler.driver.swipe(start_x, start_y, end_x, end_y, 1000)
                    except Exception as e2:
                        CrawlerLogger.debug(f"[-] Swipe method failed: {e2}")
                        # 方法3: 使用scrollGesture
                        try:
                            self.driver_handler.driver.execute_script(
                                'mobile: scrollGesture', 
                                {
                                    'left': 100, 
                                    'top': start_y, 
                                    'width': conf.CLIENT_SIDE_CONF.PHONE_WIDTH - 200, 
                                    'height': start_y - end_y,
                                    'direction': 'up',
                                    'percent': 1.0
                                }
                            )
                        except Exception as e3:
                            CrawlerLogger.debug(f"[-] scrollGesture method failed: {e3}")
                            # 所有方法都失败，抛出异常
                            raise Exception("All scroll methods failed")
                
                return True
            elif element.method == "re-scroll":
                CrawlerLogger.info(f"[+] re-scroll the phone")
                start_x = 720
                start_y = int(conf.CLIENT_SIDE_CONF.PHONE_HEIGHT * 0.1)
                end_x = 720
                end_y = int(conf.CLIENT_SIDE_CONF.PHONE_HEIGHT * 0.9)
                
                try:
                    # 方法1: 使用swipeGesture JavaScript命令
                    self.driver_handler.driver.execute_script(
                        'mobile: swipeGesture', 
                        {
                            'left': start_x, 
                            'top': start_y, 
                            'width': 10, 
                            'height': end_y - start_y,
                            'direction': 'down',
                            'percent': 1.0
                        }
                    )
                except Exception as e1:
                    CrawlerLogger.debug(f"[-] swipeGesture method failed: {e1}")
                    try:
                        # 方法2: 使用直接的swipe方法
                        self.driver_handler.driver.swipe(start_x, start_y, end_x, end_y, 1000)
                    except Exception as e2:
                        CrawlerLogger.debug(f"[-] Swipe method failed: {e2}")
                        # 方法3: 使用scrollGesture
                        try:
                            self.driver_handler.driver.execute_script(
                                'mobile: scrollGesture', 
                                {
                                    'left': 100, 
                                    'top': start_y, 
                                    'width': conf.CLIENT_SIDE_CONF.PHONE_WIDTH - 200, 
                                    'height': end_y - start_y,
                                    'direction': 'down',
                                    'percent': 1.0
                                }
                            )
                        except Exception as e3:
                            CrawlerLogger.debug(f"[-] scrollGesture method failed: {e3}")
                            # 所有方法都失败，抛出异常
                            raise Exception("All scroll methods failed")
                
                return True
        except Exception as e:
            CrawlerLogger.debug(f"[-] Click error : {e}")
            return False
        finally :
            self.driver_handler.driver.implicitly_wait(5)

    def safe_click_check_button(self):
        '''
        点击所有未选中的check按钮
        :return:
        '''
        checks_xpath = "//*[contains(@class, 'check') and not(.//*[contains(@class, 'check')])]"
        PageHandler.safe_click_elements(self.driver_handler.driver, AppiumBy.XPATH, checks_xpath)

    def safe_click_switch_button(self):
        '''
        点击所有未选中的switch按钮
        :return:
        '''
        switches_xpath = "//*[contains(@class, 'switch') and not(.//*[contains(@class, 'switch')])]"
        PageHandler.safe_click_elements(self.driver_handler.driver, AppiumBy.XPATH, switches_xpath)
